home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / inetutil.1 / inetutil / inetutils-1.1 / uucpd / uucpd.c < prev   
Encoding:
C/C++ Source or Header  |  1996-07-31  |  7.5 KB  |  326 lines

  1. /*
  2.  * Copyright (c) 1985, 1993
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Rick Adams.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. static char copyright[] =
  39. "@(#) Copyright (c) 1985, 1993\n\
  40.     The Regents of the University of California.  All rights reserved.\n";
  41. #endif /* not lint */
  42.  
  43. #ifndef lint
  44. static char sccsid[] = "@(#)uucpd.c    8.1 (Berkeley) 6/4/93";
  45. #endif /* not lint */
  46.  
  47. /*
  48.  * 4.2BSD TCP/IP server for uucico
  49.  * uucico's TCP channel causes this server to be run at the remote end.
  50.  */
  51.  
  52. #ifdef HAVE_CONFIG_H
  53. #include <config.h>
  54. #endif
  55.  
  56. #include <sys/types.h>
  57. #include <sys/wait.h>
  58. #include <sys/ioctl.h>
  59. #include <sys/socket.h>
  60. #include <netinet/in.h>
  61. #include <arpa/inet.h>
  62. #include <netdb.h>
  63. #include <signal.h>
  64. #include <fcntl.h>
  65. #include <time.h>
  66. #include <pwd.h>
  67. #include <unistd.h>
  68. #include <errno.h>
  69. #include <stdio.h>
  70. #include <stdlib.h>
  71. #include <string.h>
  72. #include <paths.h>
  73. #include <crypt.h>
  74.  
  75. void dologin ();
  76.  
  77. struct    sockaddr_in hisctladdr;
  78. int hisaddrlen = sizeof hisctladdr;
  79. struct    sockaddr_in myctladdr;
  80. int mypid;
  81.  
  82. char Username[64];
  83. char *nenv[] = {
  84.     Username,
  85.     NULL,
  86. };
  87. extern char **environ;
  88.  
  89. main(argc, argv)
  90. int argc;
  91. char **argv;
  92. {
  93. #ifndef BSDINETD
  94.     register int s, tcp_socket;
  95.     struct servent *sp;
  96. #endif !BSDINETD
  97.     extern int errno;
  98.     int dologout();
  99.  
  100.     environ = nenv;
  101. #ifdef BSDINETD
  102.     close(1); close(2);
  103.     dup(0); dup(0);
  104.     hisaddrlen = sizeof (hisctladdr);
  105.     if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) {
  106.         fprintf(stderr, "%s: ", argv[0]);
  107.         perror("getpeername");
  108.         _exit(1);
  109.     }
  110.     if (fork() == 0)
  111.         doit(&hisctladdr);
  112.     dologout();
  113.     exit(1);
  114. #else !BSDINETD
  115.     sp = getservbyname("uucp", "tcp");
  116.     if (sp == NULL){
  117.         perror("uucpd: getservbyname");
  118.         exit(1);
  119.     }
  120.     if (fork())
  121.         exit(0);
  122.     if ((s=open(_PATH_TTY, 2)) >= 0){
  123.         ioctl(s, TIOCNOTTY, (char *)0);
  124.         close(s);
  125.     }
  126.  
  127.     bzero((char *)&myctladdr, sizeof (myctladdr));
  128.     myctladdr.sin_family = AF_INET;
  129.     myctladdr.sin_port = sp->s_port;
  130. #ifdef BSD4_2
  131.     tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
  132.     if (tcp_socket < 0) {
  133.         perror("uucpd: socket");
  134.         exit(1);
  135.     }
  136.     if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) {
  137.         perror("uucpd: bind");
  138.         exit(1);
  139.     }
  140.     listen(tcp_socket, 3);    /* at most 3 simultaneuos uucp connections */
  141.     signal(SIGCHLD, dologout);
  142.  
  143.     for(;;) {
  144.         s = accept(tcp_socket, &hisctladdr, &hisaddrlen);
  145.         if (s < 0){
  146.             if (errno == EINTR) 
  147.                 continue;
  148.             perror("uucpd: accept");
  149.             exit(1);
  150.         }
  151.         if (fork() == 0) {
  152.             close(0); close(1); close(2);
  153.             dup(s); dup(s); dup(s);
  154.             close(tcp_socket); close(s);
  155.             doit(&hisctladdr);
  156.             exit(1);
  157.         }
  158.         close(s);
  159.     }
  160. #endif BSD4_2
  161.  
  162. #endif    !BSDINETD
  163. }
  164.  
  165. void
  166. doit (sinp)
  167.      struct sockaddr_in *sinp;
  168. {
  169.     struct passwd *pw, *getpwnam();
  170.     char user[64], passwd[64];
  171.     char *xpasswd;
  172.  
  173.     alarm(60);
  174.     printf("login: "); fflush(stdout);
  175.     if (readline(user, sizeof user) < 0) {
  176.         fprintf(stderr, "user read\n");
  177.         return;
  178.     }
  179.     /* truncate username to 8 characters */
  180.     user[8] = '\0';
  181.     pw = getpwnam(user);
  182.     if (pw == NULL) {
  183.         fprintf(stderr, "user unknown\n");
  184.         return;
  185.     }
  186.     if (strcmp(pw->pw_shell, _PATH_UUCICO)) {
  187.         fprintf(stderr, "Login incorrect.");
  188.         return;
  189.     }
  190.     if (pw->pw_passwd && *pw->pw_passwd != '\0') {
  191.         printf("Password: "); fflush(stdout);
  192.         if (readline(passwd, sizeof passwd) < 0) {
  193.             fprintf(stderr, "passwd read\n");
  194.             return;
  195.         }
  196.         xpasswd = CRYPT (passwd, pw->pw_passwd);
  197.         if (strcmp(xpasswd, pw->pw_passwd)) {
  198.             fprintf(stderr, "Login incorrect.");
  199.             return;
  200.         }
  201.     }
  202.     alarm(0);
  203.     sprintf(Username, "USER=%s", user);
  204.     dologin(pw, sinp);
  205.     setgid(pw->pw_gid);
  206. #ifdef BSD4_2
  207.     initgroups(pw->pw_name, pw->pw_gid);
  208. #endif BSD4_2
  209.     chdir(pw->pw_dir);
  210.     setuid(pw->pw_uid);
  211. #ifdef BSD4_2
  212.     execl(UUCICO, "uucico", (char *)0);
  213. #endif BSD4_2
  214.     perror("uucico server: execl");
  215. }
  216.  
  217. readline(p, n)
  218. register char *p;
  219. register int n;
  220. {
  221.     char c;
  222.  
  223.     while (n-- > 0) {
  224.         if (read(0, &c, 1) <= 0)
  225.             return(-1);
  226.         c &= 0177;
  227.         if (c == '\n' || c == '\r') {
  228.             *p = '\0';
  229.             return(0);
  230.         }
  231.         *p++ = c;
  232.     }
  233.     return(-1);
  234. }
  235.  
  236. #include <utmp.h>
  237. #ifdef BSD4_2
  238. #include <fcntl.h>
  239. #endif BSD4_2
  240.  
  241. #define    SCPYN(a, b)    strncpy(a, b, sizeof (a))
  242.  
  243. struct    utmp utmp;
  244.  
  245. dologout()
  246. {
  247.     union wait status;
  248.     int pid;
  249.  
  250. #ifdef BSDINETD
  251.     while ((pid=wait((int *)&status)) > 0) {
  252. #else  !BSDINETD
  253.     while ((pid=wait3((int *)&status,WNOHANG,0)) > 0) {
  254. #endif !BSDINETD
  255.  
  256. #ifdef HAVE_LOGWTMP
  257.         char line[100];
  258.         sprintf(line, "uucp%.4d", pid);
  259.         logwtmp (line, "", "");
  260. #else
  261.         int wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND);
  262.         if (wtmp >= 0) {
  263.             SCPYN(utmp.ut_name, "");
  264.             SCPYN(utmp.ut_host, "");
  265.             (void) time(&utmp.ut_time);
  266.             (void) write(wtmp, (char *)&utmp, sizeof (utmp));
  267.             (void) close(wtmp);
  268.         }
  269. #endif
  270.     }
  271. }
  272.  
  273. /*
  274.  * Record login in wtmp file.
  275.  */
  276. void
  277. dologin(pw, sin)
  278.      struct passwd *pw;
  279.      struct sockaddr_in *sin;
  280. {
  281.     char line[32];
  282.     char remotehost[32];
  283.     int wtmp, f;
  284.     struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr,
  285.         sizeof (struct in_addr), AF_INET);
  286.  
  287.     if (hp) {
  288.         strncpy(remotehost, hp->h_name, sizeof (remotehost));
  289.         endhostent();
  290.     } else
  291.         strncpy(remotehost, inet_ntoa(sin->sin_addr),
  292.             sizeof (remotehost));
  293.  
  294.     sprintf(line, "uucp%.4d", getpid());
  295.  
  296. #ifdef HAVE_LOGWTMP
  297.     logwtmp (line, pw->pw_name, remotehost);
  298. #else
  299.     /* Do things the old bsd way.  */
  300.     wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND);
  301.     if (wtmp >= 0) {
  302.         /* hack, but must be unique and no tty line */
  303.         SCPYN(utmp.ut_line, line);
  304.         SCPYN(utmp.ut_name, pw->pw_name);
  305.         SCPYN(utmp.ut_host, remotehost);
  306.         time(&utmp.ut_time);
  307.         (void) write(wtmp, (char *)&utmp, sizeof (utmp));
  308.         (void) close(wtmp);
  309.     }
  310. #endif
  311.  
  312. #ifdef _PATH_LASTLOG
  313.     if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) {
  314.         struct lastlog ll;
  315.  
  316.         time(&ll.ll_time);
  317.         lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0);
  318.         strcpy(line, remotehost);
  319.         SCPYN(ll.ll_line, line);
  320.         SCPYN(ll.ll_host, remotehost);
  321.         (void) write(f, (char *) &ll, sizeof ll);
  322.         (void) close(f);
  323.     }
  324. #endif
  325. }
  326.